﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using RTracker.Models.Organization;
using RTracker.Models.Common;
using RTracker.Models.User;
using System.Configuration;



namespace RTracker.Controllers
{
    [OutputCache(Duration = 0, NoStore = true)]
    public class AppBaseController : Controller
    {
        //store default session time out value from config settings.
        public static int DefaultTimeOut = 20;
        //Convert.ToInt32(ConfigurationManager.AppSettings["SessionTimeout"].ToString());

        /// <summary>
        /// Object of type CAuthenticationContext. Used to store Authentication object which we create at login tym and send with each api request to get or set data.
        /// </summary>
        public CAuthenticationContext AuthenticationContext
        {
            get
            {
                if (Session["AuthenticationContext"] != null)                       // checks for the authentication context in session.
                    return (CAuthenticationContext)Session["AuthenticationContext"];
                else
                    return new CAuthenticationContext() { UserId = 1 };
            }
            set
            {
                Session["AuthenticationContext"] = value;
            }
        }


        /// <summary>
        /// Object of type CUserSession. Used to get and set Current logged in user's information from session.
        /// </summary>
        public CUserSession CurrentUserSession
        {
            get
            {
                if (Session["CurrentUserSession"] != null)             // checks for the current user in session
                    return (CUserSession)Session["CurrentUserSession"];
                else
                    return new CUserSession();
            }
            set
            {
                Session["CurrentUserSession"] = value;
            }
        }

        /// <summary>
        /// Used to store value of session time out for session variables.
        /// </summary>
        public int SessionTimeOut
        {
            get
            {
                if (Session["SessionTimeOut"] != null)          // checks the whether session time out has occured or not
                    return (int)Session["SessionTimeOut"];
                else
                    return DefaultTimeOut;
            }
            set
            {
                Session["SessionTimeOut"] = value;
            }
        }

        /// <summary>
        /// List of type CUserSession. Used to get and set all logged in users information in application level variable.
        /// </summary>
        /// <returns>List of type CUserSession in Application variable</returns>
        public List<CUserSession> ApplicationUsers
        {
            get
            {
                if (HttpContext.Application["SessionUsers"] != null)
                    return (List<CUserSession>)HttpContext.Application["SessionUsers"];
                else
                    return new List<CUserSession>();
            }
            set
            { HttpContext.Application["SessionUsers"] = value; }
        }

        /// <summary>
        /// list of the permissions of currently logged in user.
        /// </summary>
        /// <returns>List of type CUserPermissions in Application variable</returns>
        public List<CUserPermissions> CurrentUserPermissions
        {
            get
            {
                if (HttpContext.Application["CurrentUserPermissions"] != null)
                    return (List<CUserPermissions>)HttpContext.Application["CurrentUserPermissions"];
                else
                    return new List<CUserPermissions>();
            }
            set
            { HttpContext.Application["CurrentUserPermissions"] = value; }
        }


        /// <summary>
        /// List of type CUserSession. Used to get and set all logged in users information in application level variable.
        /// </summary>
        /// <returns>List of type CUserSession in Application variable</returns>
        public List<CUser> ApplicationUsersList
        {
            get
            {
                if (HttpContext.Application["UsersList"] != null)
                    return (List<CUser>)HttpContext.Application["UsersList"];
                else
                    return new List<CUser>();
            }
            set
            { HttpContext.Application["UsersList"] = value; }
        }
        /// <summary>
        /// This method is used to user's last action time in session.
        /// in this first we check if session is not timed out then update its last action time else not.
        /// </summary>
        /// <returns>true or false</returns>
        [HttpPost]
        public bool UpdateLastActionTime()
        {
            try
            {
                if (CurrentUserSession != null && CurrentUserSession.UserId > 0)
                {
                    //get time difference of last action time and date time now and compare it with session time out.
                    TimeSpan span = DateTime.Now.Subtract(Convert.ToDateTime(CurrentUserSession.LastActionTime));
                    double SessionTime = Convert.ToDouble(SessionTimeOut);
                    if (SessionTime > span.TotalMinutes)
                    {
                        CurrentUserSession.LastActionTime = DateTime.Now.ToString();
                        return true;
                    }
                }


                return false;
            }
            catch (Exception)
            {

                return false;
            }
        }

        /// <summary>
        /// checkUserPermission
        /// </summary>
        /// <param name="nPermissionId"></param>
        /// <returns></returns>
        public bool checkUserPermission(Int32 nPermissionId)
        {
            bool _bPermissionStatus = true;
            //bool _bPermissionStatus = false;

            //if (CurrentUserPermissions.Where(a => a.ActionId == nPermissionId).ToList().Count > 0)
            //{
            //    _bPermissionStatus = true;
            //}

            return _bPermissionStatus;
        }


        /// <summary>
        /// This method checks for user session time out.
        /// first we check for Current logged in user session, if exists then get last action time of current user from session
        /// now check the difference of last action time and current time if it is greater than session time out value(from session) then it means session is timed out,
        /// then return false else update the last action time in session varable of current user info return true.
        /// </summary>
        /// <returns>return false if session time out, or true in case not expired.</returns>
        public bool checkSessionTimeOut()
        {
            // bool type variable to store session time out state
            bool IsSessionTimedOut = true;
            try
            {
                //check if current logged in user session exists or not.
                if (CurrentUserSession != null && CurrentUserSession.UserId > 0)
                {
                    //get time difference of last action time of current user and current time
                    TimeSpan span = DateTime.Now.Subtract(Convert.ToDateTime(CurrentUserSession.LastActionTime));
                    //get session time out value from session variable.
                    double SessionTime = Convert.ToDouble(SessionTimeOut);
                    // check if time difference is greater than session time out then set session time out state variable to true
                    if (span.TotalMinutes > SessionTime)
                    {
                        IsSessionTimedOut = true;
                    }
                    //else set session time out variable to false and update last action time of current user to current time.
                    else
                    {
                        IsSessionTimedOut = false;
                        CurrentUserSession.LastActionTime = DateTime.Now.ToString();
                    }

                }
            }
            catch (Exception)
            {
                //incase of any exception set session time out variable to true.
                IsSessionTimedOut = true;
            }


            return IsSessionTimedOut;
        }


        /// <summary>
        /// CheckLocksByOther purpose: to check if currently selected record is softlock or hardlock by other or not.
        /// </summary>
        /// <param name="obj">dynamic object we can pass any object which cantains SoftLockedBy and HardLockedBy fields </param>
        /// <returns></returns>
        public bool CheckLocksByOther(dynamic obj)
        {
            if (DisplayInfo(obj, "SoftLockedBy").Equals(CurrentUserSession.UserId.ToString()) || DisplayInfo(obj, "HardLockedBy").Equals(CurrentUserSession.UserId.ToString()))
            {
                return false;    
            }
            return true;
        }


        /// <summary>
        /// DisplayInfo gives Value of property from dynamic object passed
        /// </summary>
        /// <param name="obj">dynamic object which can receive any type of object</param>
        /// <param name="property">property to be exacted from the object</param>
        /// <returns>Value of property</returns>
        public string DisplayInfo(dynamic obj, string property)
        {
            var value = "";
            try
            {

                // check if property is not null 
                if (property != null)
                {
                    //getting value of property from dynamic object using its property name.
                    value = Convert.ToString(obj.GetType().GetProperty(property).GetValue(obj, null));
                }


            }
            catch (Exception ex)
            { throw ex; }
            return value;
        }

        /// <summary>
        /// This method checks for user session.
        /// in this first we check for the list of logged in users from application variable
        /// now we check for current logged in user with session key in list if there is no record for this means this user is logout by other at some other place.
        /// now check for session time out state of user 
        /// </summary>
        /// <returns>Object of type String</returns>
        /// 
        [HttpPost]
        public string CheckSessionState()
        {
            try
            {
                // get all logged in users in a list of type CUserSession.
                List<CUserSession> oSessionUsersList = ApplicationUsers;
                //check if list is not null and it contains record and current logged in user session exists.
                if (oSessionUsersList != null && oSessionUsersList.Count > 0 && CurrentUserSession.UserId > 0)
                {

                    //check for session time out state
                    if (checkSessionTimeOut())
                    {
                        return CAppErrorsConstants.SessionMessage;   // means session is timed out.
                    }
                    else
                    {
                        return CAppConstants.SessionSuccess;//means session not expired.
                    }

                }
                return CAppErrorsConstants.NoSession;
            }
            catch (Exception)
            {

                return CAppErrorsConstants.NoSession;
            }
            return CAppErrorsConstants.NoSession;
        }

        /// <summary>
        /// It clears the users session and then abandons it.
        /// </summary>
        /// <returns>returns true when function succeeded</returns>
        ///
        [HttpPost]
        public bool ClearSession()
        {
            Session.Clear();
            Session.Abandon();
            HttpContext.Session.Clear();
            HttpContext.Session.Abandon();
            return true;
        }

        /// <summary>
        /// It checks for login status of user for this instance
        /// in this we check for session variable if it exist means user is logged in another tab
        /// if not exist then we create session for furthur check
        /// </summary>
        /// <returns>returns true if user is logged in another tab.</returns>
        ///
        [HttpPost]
        public bool CheckLoginStatus()
        {
            if (Session["Isloaded"] == null || !(bool)Session["Isloaded"])
            {
                Session["Isloaded"] = true;
                return false;
            }
            else
            {
                return true;
            }
        }
        /// <summary>
        /// This function is used to get fullname of the user on the basis of user id from user list
        /// </summary>
        /// <param name="id">user id of type int</param>
        /// <returns>string type fullname</returns>
        public string GetFullName(int id)
        {
            // In this function we get list of all users stored in application variable
            // From this list we get firstname and lastname of that user whose id is passed as parameter
            // then we concatinate that firstname and lastname to form fullname
            string strFullName = "";
            try
            {


                List<CUser> lstCUser = new List<CUser>();
                lstCUser = ApplicationUsersList;

                string strFirstName = "";
                string strLastName = "";
                //check if user count in application variable is greater than zero
                // then find user's first and last name from list 
                if (lstCUser.Count > 0)
                {
                    strFirstName = lstCUser.Where(m => m.UserId == id).FirstOrDefault().FirstName;
                    strLastName = lstCUser.Where(m => m.UserId == id).FirstOrDefault().LastName;
                    strFullName = strFirstName + " " + strLastName;
                }
            }
            catch (Exception)
            {

                strFullName = "";
            }
            return strFullName;
        }

        public void GetAllApplicationUsers()
        {
            try
            {
                List<CUser> temp_userList = new List<CUser>();
                MUser oMUser = new MUser();
                oMUser.GetAllUserList(out temp_userList);

                ApplicationUsersList = temp_userList;
            }
            catch (Exception)
            {

            }
        }
    }
}